﻿#include <stdlib.h>
#include "CMetalSlug.h"

#define BACKGROUND  "Map1.png"
#define MARCO		"Leg_Run1_31x20_18.png"
#define MARCO_LEG_JUMP_UP	"Leg_Jump_18_24_1.png"
#define MARCO_LEG_RUN		"Leg_Run1_31x20_18.png"
#define MARCO_LEG_STANDON	"Leg_StandOn_21x16_4_16.png"

#define GROUND_Y	600	//the ground
#define MAX_Y		260				//the max jump

#define RIGHT	0
#define LEFT	1

CMetalSlug::CMetalSlug(HINSTANCE hInstance, LPCSTR GameName, int iMode, bool bIsWindowed, int iFPS):
CGame(hInstance, GameName, iMode, bIsWindowed, iFPS)
{	
	scale = (float)mi_ScreenWidth / 320 - 0.4f;
	m_bIsAction = false;
	m_BackGround = NULL;
	Tree = new CQuadTree(1363*scale, 600);
	Screen = new CScreen( 0, 0, 1363*scale, 600);
}

CMetalSlug::~CMetalSlug()
{
	Tree = NULL;
}

//virtual methods
void CMetalSlug::LoadResource()
{
	m_BackGround = CGame::CreateSurfaceFromFile(BACKGROUND);

	HRESULT result = D3DXCreateSprite(mp_Direct3D->GetDirectDevice(), &m_SpriteHandler);

	mp_Direct3D->GetDirectDevice()->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &m_BackBuffer);
	
	Marco = new CMarco(m_SpriteHandler, scale, Tree);
	Rebel = new CRebel(m_SpriteHandler, scale, Tree);
	Tree->AddObj(Tree->m_qRoot, Marco);
	Tree->AddObj(Tree->m_qRoot, Rebel);
	InitRebel();
}

void CMetalSlug::ProcessInput(void)
{
	//LEFT ARROW press event
	//run to the left
	if (KEY_DOWN(DIK_LEFT))  
	{	
		if (Marco->mb_IsJump)
		{
			Marco->mf_vx = -0.5;
			return;
		}
		
		if (KEY_DOWN(DIK_SPACE))
		{
			Marco->JumpFar(LEFT);
		}
		else if (KEY_DOWN(DIK_Z))
		{
			Marco->Shot();			
		}
		else if (KEY_DOWN(DIK_X))
		{
			Marco->ThrowGrenade();
		}
		
		else if (KEY_DOWN(DIK_UP))
		{
			if (KEY_DOWN(DIK_Z))
			{
				Marco->ShotUp();
			}
		}

		if (!Marco->mb_IsJump)
		{
			Marco->Run(LEFT);
		}

		mdw_LastKeyPress = GetTickCount();
	}
	//RIGHT ARROW press event
	//run to the right
	else if (KEY_DOWN(DIK_RIGHT))
	{
		
		//m_bIsAction = true;
		//Rebel->Crawl();
		
		if (Marco->mb_IsJump)
		{
			Marco->mf_vx= 0.5f;
			return;
		}
		if (KEY_DOWN(DIK_SPACE))
		{
			Marco->JumpFar(RIGHT);
		}
		else if (KEY_DOWN(DIK_Z))
		{
			Marco->Shot();			
		}
		else if (KEY_DOWN(DIK_X))
		{
			Marco->ThrowGrenade();
		}
		
		else if (KEY_DOWN(DIK_UP))
		{
			if (KEY_DOWN(DIK_Z))
			{
				
				Marco->ShotUp();
			}
		}
		if (!Marco->mb_IsJump)
		{
			Marco->Run(RIGHT);
		}
		mdw_LastKeyPress = GetTickCount();
		//Tree->UpdatePosition(Tree->m_qRoot);
	}

	//DOWN ARROW press event
	//crouch move and shoting down
	else if (KEY_DOWN(DIK_DOWN))
	{
		if (KEY_DOWN(DIK_B))
		{
			Marco->CrouchMove(RIGHT);
		}
		else if (KEY_DOWN(DIK_V))
		{
			Marco->CrouchMove(LEFT);
		}
		else if (KEY_DOWN(DIK_Z))
		{
			Marco->CrouchShot();
		}
		else
		{
			Marco->Crouch();
		}
		mdw_LastKeyPress = GetTickCount();
	}

	//UP ARROW press event
	//shoting up to the air
	else if (KEY_DOWN(DIK_UP))
	{
		if (KEY_DOWN(DIK_Z))
		{
			Marco->ShotUp();
		}
	}

	//SPACE ARROW press event
	//jump up and jump far
	else if (KEY_DOWN(DIK_SPACE))
	{ 
		if (Marco->mb_IsJump)
			return;
		
		Marco->JumpUp();
		mdw_LastKeyPress = GetTickCount();
	}

	//Z ARROW press event
	//Shoting event
	else if (KEY_DOWN(DIK_Z))
	{
		if (Marco->mb_IsAction)
		{
			Marco->mb_ShotContinue = true;
			return;
		}
		Marco->Shot();
		
		mdw_LastKeyPress = GetTickCount();
	}

	//LEFT ARROW press event
	//Throw greanade event
	else if (KEY_DOWN(DIK_X))
	{
		Marco->ThrowGrenade();
		
		mdw_LastKeyPress = GetTickCount();
	}

	//nothing pressed
	//stand and relax event
	else
	{
		DWORD now = GetTickCount();

		if (Marco->mb_IsJump)
		{
			return;
		}
		else
		{
			if ( !(Marco->mb_IsRelax)&&(now - mdw_LastKeyPress)/1000 > 5)
			{
				Marco->Relax();
				mdw_LastKeyPress = now;
			}
			else
			{
				Marco->Stand();
			}
		}
	}
}

void CMetalSlug::RenderFrame(void)
{
	//update the object draw 
	Tree->updateDraw(Screen->m_RCamera, mdw_DeltaTime, Screen->m_RCamera.left);
	RECT r;
	r.left = Screen->m_RCamera.left/scale;
	r.top = 0;
	r.right = Screen->m_RCamera.right/scale;
	r.bottom = 289;

	mp_Direct3D->GetDirectDevice()->StretchRect(m_BackGround,	//from
												&r,			//which protion
												m_BackBuffer,	//to
												NULL,			//which protion
												D3DTEXF_POINT);	//filter which is decide how to stretch the source image to Destination Rect
	
	//lock the surface so that the sprite can be draw
	m_SpriteHandler->Begin(D3DXSPRITE_ALPHABLEND); 
	
	//set the sampler state that tell the device which technology will be use to render
	mp_Direct3D->GetDirectDevice()->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
	//Marco->Render();
	if(Marco->m_nAndr >= 350 && Marco->m_nAndr < 2520)
		Screen->MoveCamera(Marco->Stormove);

	Tree->DrawObj(Screen->m_RCamera);

	Object* obj;
	/*char str[25];
	itoa(Marco->Bullet->m_ObRect->bottom, str, 10);
	if(Marco->Bullet->m_ObRect->left > 0)
		MessageBox(NULL, str , "Error", MB_OK);*/
	obj = Tree->CheckCollision(Tree->m_qRoot, *Marco->Bullet->m_ObRect, 0);
	if(obj != NULL)
	{
		obj->Die();
		
		Marco->Bullet->ix = 851;
		Marco->Bullet->setRect(Screen->m_RCamera.left);
	}
	//unlock the surface for other processes to use
	m_SpriteHandler->End();
}

void CMetalSlug::InitRebel()
{
	Rebel = new CRebel(m_SpriteHandler, scale, Tree);
	Rebel->m_nAndr = 700;
	Rebel->m_fX = 0;
	Rebel->Move();
	Tree->AddObj(Tree->m_qRoot, Rebel);
}
void CMetalSlug::SetupTree()
{
	//Tree->Setup(m_Rebel);
}

void CMetalSlug::OnKeyUp(int iKeyCode)
{
}

void CMetalSlug::OnKeyDown(int iKeyCode)
{	
}

